<p>This rule raises an issue when a generic exception (such as <code>Exception</code>, <code>SystemException</code>,
<code>ApplicationException</code>, <code>IndexOutOfRangeException</code>, <code>NullReferenceException</code>, <code>OutOfMemoryException</code> or
<code>ExecutionEngineException</code>) is thrown.</p>
<h2>Why is this an issue?</h2>
<p>Throwing general exceptions such as <code>Exception</code>, <code>SystemException</code> and <code>ApplicationException</code> will have a negative
impact on any code trying to catch these exceptions.</p>
<p>From a consumer perspective, it is generally a best practice to only catch exceptions you intend to handle. Other exceptions should ideally not be
caught and let to propagate up the stack trace so that they can be dealt with appropriately. When a generic exception is thrown, it forces consumers
to catch exceptions they do not intend to handle, which they then have to re-throw.</p>
<p>Besides, when working with a generic type of exception, the only way to distinguish between multiple exceptions is to check their message, which is
error-prone and difficult to maintain. Legitimate exceptions may be unintentionally silenced and errors may be hidden.</p>
<p>For instance, if an exception such as <code>StackOverflowException</code> is caught and not re-thrown, it may prevent the program from terminating
gracefully.</p>
<p>When throwing an exception, it is therefore recommended to throw the most specific exception possible so that it can be handled intentionally by
consumers.</p>
<p>Additionally, some reserved exceptions should not be thrown manually. Exceptions such as <code>IndexOutOfRangeException</code>,
<code>NullReferenceException</code>, <code>OutOfMemoryException</code> or <code>ExecutionEngineException</code> will be thrown automatically by the
runtime when the corresponding error occurs. Many of them indicate serious errors, which the application may not be able to recover from. It is
therefore recommended to avoid throwing them as well as using them as base classes.</p>
<h2>How to fix it</h2>
<p>To fix this issue, make sure to throw specific exceptions that are relevant to the context in which they arise. It is recommended to either:</p>
<ul>
  <li> Throw a subtype of <code>Exception</code> when one matches. For instance <code>ArgumentException</code> could be raised when an unexpected
  argument is provided to a function. </li>
  <li> Define a custom exception type that derives from <code>Exception</code> or one of its subclasses. </li>
</ul>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
Public Sub DoSomething(obj As Object)
  If obj Is Nothing Then
    ' Noncompliant
    Throw New NullReferenceException("obj") ' Noncompliant: This reserved exception should not be thrown manually
  End If
  ' ...
End Sub
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
Public Sub DoSomething(obj As Object)
  If obj Is Nothing Then
    Throw New ArgumentNullException("obj") ' Compliant: this is a specific and non-reserved exception type
  End If
  ' ...
End Sub
</pre>
<h2>Resources</h2>
<h3>Standards</h3>
<ul>
  <li> CWE - <a href="https://cwe.mitre.org/data/definitions/397">CWE-397 Declaration of Throws for Generic Exception</a> </li>
</ul>

